package me.suntao.javaio.client.nio2;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;

public class Nio2ClientHandler implements CompletionHandler<Void,Nio2ClientHandler>,Runnable {
  private AsynchronousSocketChannel socketChannel;
  private String host;
  private int port;
  private CountDownLatch latch;

  public Nio2ClientHandler(String host, int port) {
    this.host = host;
    this.port = port;
    this.host=host;
    this.port=port;
    try {
      socketChannel= AsynchronousSocketChannel.open();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override public void completed(Void result, Nio2ClientHandler attachment) {
    //准备写入服务器端数据
    String msg = String
                   .format("clientname:%s, senttime:%s", Thread.currentThread().getName(), System.currentTimeMillis());
    final byte[] bytes = msg.getBytes();
    final ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
    writeBuffer.put(bytes);
    writeBuffer.flip();
    //写入数据
    socketChannel.write(writeBuffer, writeBuffer, new CompletionHandler<Integer, ByteBuffer>() {
      @Override public void completed(Integer result, ByteBuffer attachment) {
        //没写完继续
        if(attachment.hasRemaining()){
          socketChannel.write(attachment,attachment,this);
        }else{
          ByteBuffer readBuffer = ByteBuffer.allocate(1024);
          socketChannel.read(readBuffer, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override public void completed(Integer result, ByteBuffer attachment) {
              attachment.flip();
              byte[]  body= new byte[attachment.remaining()];
              attachment.get(body);
              try {
                String bodyStr=new String(bytes,"UTF-8");
                System.out.println(bodyStr);
                latch.countDown();
              } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
              }
            }

            @Override public void failed(Throwable exc, ByteBuffer attachment) {
              try {
                socketChannel.close();
              } catch (IOException e) {
                e.printStackTrace();
              }
            }
          });
        }
      }

      @Override public void failed(Throwable exc, ByteBuffer attachment) {
        try {
          socketChannel.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    });
  }

  @Override public void failed(Throwable exc, Nio2ClientHandler attachment) {
    try {
      socketChannel.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override public void run() {
    latch=new CountDownLatch(1);
    socketChannel.connect(new InetSocketAddress(port),this,this);
    try {
      latch.await();
      socketChannel.close();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
